package cn.core.tool.service;

import cn.core.tool.ao.DataExportAO;
import cn.core.tool.ao.DataExportFieldAO;
import cn.core.tool.context.CoreContextData;
import cn.core.tool.eo.DataManipulationLog;
import cn.core.tool.eo.Files;
import cn.core.tool.exception.CoreException;
import cn.core.tool.mapper.CoreMapper;
import cn.core.tool.util.CoreTool;
import cn.hutool.poi.excel.BigExcelWriter;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.google.gson.Gson;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.*;

/**
 * 文件 服务
 */
@Log4j2
@Service
public class FileService {

  @Value("${proconf.file-sv-type}")
  private String fileSvType;

  @Value("${proconf.local-file-path}")
  private String localFilePath;

  @Value("${proconf.file-path-prefix}")
  private String filePathPrefix;

  @Resource
  private CoreMapper coreMapper;

  @Resource
  private Gson gson;

  /**
   * 数据导出参数 >>> 文件url
   */
  public String getFileUrlByDataExportAO(DataExportAO<?> ao) throws Exception {
    try {
      String r = "";
      if (ao.getBigDataExport() != null && ao.getBigDataExport()) {
        BigExcelWriter writer = ExcelUtil.getBigWriter();
        for (DataExportFieldAO eo : ao.getDataExportFieldConf()) {
          writer.addHeaderAlias(eo.getFieldName(), eo.getFieldComment());
        }
        writer.setOnlyAlias(true);
        writer.write(ao.getData(), true);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        writer.flush(baos);
        r = this.getFileUrlByFileStream(baos.toByteArray(), CoreTool.isNotNullStr(ao.getFileModule()) ? ao.getFileModule() : "dataExport", CoreTool.isNotNullStr(ao.getFileName()) ? ao.getFileName() : "数据导出.xlsx");
        baos.close();
        writer.close();
      } else {
        ExcelWriter writer = ExcelUtil.getWriter(true);
        for (DataExportFieldAO eo : ao.getDataExportFieldConf()) {
          writer.addHeaderAlias(eo.getFieldName(), eo.getFieldComment());
        }
        writer.setOnlyAlias(true);
        writer.write(ao.getData(), true);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        writer.flush(baos);
        r = this.getFileUrlByFileStream(baos.toByteArray(), CoreTool.isNotNullStr(ao.getFileModule()) ? ao.getFileModule() : "dataExport", CoreTool.isNotNullStr(ao.getFileName()) ? ao.getFileName() : "数据导出.xlsx");
        baos.close();
        writer.close();
      }
      return r;
    } catch (Exception e) {
      if (log.isDebugEnabled()) {
        log.error(e.getMessage(), e);
      }
      throw e;
    }
  }

  /**
   * 文件流 >>> 文件url
   */
  public String getFileUrlByFileStream(byte[] fileStream, String fileModule, String fileName) throws Exception {
    try {
      String r = "";
      if (fileStream != null) {
        if ("local".equals(fileSvType)) {
          String fileId = CoreTool.getUUID32();
          StringBuilder fileUrl = new StringBuilder();
          fileUrl.append(filePathPrefix)
              .append("/")
              .append(fileModule)
              .append("/")
              .append(CoreTool.getCurrentFormatTime("yyyy/MM/dd"))
              .append("/")
              .append(fileId)
              .append(fileName.lastIndexOf(".") != -1 ? fileName.substring(fileName.lastIndexOf(".")) : "");
          r = fileUrl.toString();
          String path = localFilePath + fileUrl.toString();
          File f = new File(path);
          if (!f.exists()) {
            new File(path.substring(0, path.lastIndexOf("/"))).mkdirs();
          }
          try (FileOutputStream fos = new FileOutputStream(f)) {
            fos.write(fileStream);
          } catch (IOException e) {
            e.printStackTrace();
          }
          Files saveFiles = new Files()
              .setId(fileId)
              .setFileModule(fileModule)
              .setFileName(fileName)
              .setFileUrl(fileUrl.toString())
              .setUploadTimes(CoreTool.getCurrentTimeStamp());
          DataManipulationLog saveDataManipulationLog = new DataManipulationLog()
              .setId(CoreTool.getUUID32())
              .setOperationMethod("save")
              .setNexusType(CoreContextData.getCurrentContextData() != null ? CoreContextData.getCurrentContextData().getNexusType() : null)
              .setOperationId(CoreContextData.getCurrentContextData() != null ? CoreContextData.getCurrentContextData().getUsrId() : null)
              .setOperationAid(CoreContextData.getCurrentContextData() != null ? CoreContextData.getCurrentContextData().getAccountId() : null)
              .setOperationName(CoreContextData.getCurrentContextData() != null ? CoreContextData.getCurrentContextData().getUsrname() : null)
              .setOperationTimes(System.currentTimeMillis())
              .setDataObjectClassName("cn.core.dirs.eo.Files")
              .setDataId(fileId)
              .setDataContent(gson.toJson(saveFiles));
          coreMapper.saveFiles(saveFiles);
          coreMapper.saveDataManipulationLog(saveDataManipulationLog);
        } else if ("qiniu-kodo".equals(fileSvType)) {
        } else if ("aliyun-oss".equals(fileSvType)) {
        } else if ("tencent-cos".equals(fileSvType)) {
        } else {
        }
      }
      return r;
    } catch (Exception e) {
      if (log.isDebugEnabled()) {
        log.error(e.getMessage(), e);
      }
      throw e;
    }
  }

  /**
   * 文件url >>> 文件流
   */
  public byte[] getFileStreamByFileUrl(String fileUrl) throws Exception {
    try {
      byte[] r = null;
      if (CoreTool.isNotNullStr(fileUrl)) {
        if ("local".equals(fileSvType)) {
          try (FileInputStream fileInputStream = new FileInputStream(localFilePath + fileUrl)) {
            r = IOUtils.toByteArray(fileInputStream);
          } catch (IOException e) {
            throw new CoreException(CoreException.E_ERR);
          }
        } else if ("qiniu-kodo".equals(fileSvType)) {
        } else if ("aliyun-oss".equals(fileSvType)) {
        } else if ("tencent-cos".equals(fileSvType)) {
        } else {
        }
      }
      return r;
    } catch (Exception e) {
      if (log.isDebugEnabled()) {
        log.error(e.getMessage(), e);
      }
      throw e;
    }
  }

}
